//
//  CJUUID.swift
//  CJPack
//
//  Created by 陈警卫 on 2023-04-23.
//

import UIKit
import Foundation
import AdSupport

public class CJUUID {
    
    /// 随机uuid
    public class func uuidRandom() -> String? {
        let cfuuid = CFUUIDCreate(kCFAllocatorDefault)
        let cfuuid_string = CFUUIDCreateString(kCFAllocatorDefault, cfuuid)
        let uuid = (cfuuid_string as? String)?.uppercased()
        return uuid
    }
    
    /// IDFV 卸载安装后不一样
    /// 在同一设备中 该供应商的所有App的 IDFV相同
    /// 应用删除该供应商所有App 重新下载App时 IDFV发生变化
    public class func uuidIDFV() -> String? {
        let idfv = UIDevice.current.identifierForVendor?.uuidString
        return idfv
    }
    
    /// IDFA
    /// 不会因为应用卸载改变
    /// 但是用户在 设置-隐私-跟踪 里面限制跟踪后 会变成 @"00000000-0000-0000-0000-000000000000"
    /// 重新打开后会改变 原广告标识符也会改变
    public class func uuidIDFA() -> String? {
        let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
        return idfa
    }
    
    /// 唯一uuid
    /// (Keychain + IDFA)
    public class func uuidKeychain() -> String? {
        let key = (CJDevice.bundleID ?? "") + "cj.uuid.idfa"
        var uuid = CJKeychainStore.load(service: key) as? String
        if uuid == "" || uuid == nil {
            uuid = uuidIDFA()
        }
        if uuid?.count == 0 || uuid == "00000000-0000-0000-0000-000000000000" {
            uuid = uuidRandom()
        }
        if let uuid = uuid, uuid != (CJKeychainStore.load(service: key) as? String) {
            CJKeychainStore.save(service: key, data: uuid)
        }
        return uuid
    }
    
}

public class CJKeychainStore {
    
    public static func archivedDataWithObject(_ object: Any) -> Data? {
        return try? NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)
    }
    
    public static func unarchivedObject(_ data: Data) -> Any? {
        return NSKeyedUnarchiver.unarchiveObject(with: data)
    }
    /// 获取query
    public class func keychainQuery(service: String) -> [String: AnyObject] {
        let query = [kSecClass as String: kSecClassInternetPassword as AnyObject,
                     kSecAttrServer as String: service as AnyObject,
                     kSecAttrAccount as String: service as AnyObject,
                     kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock as AnyObject]
        return query
    }
    
    /// 初始化加载
    public class func load(service: String) -> AnyObject? {
        var unarchivedData: AnyObject?
        
        var query = self.keychainQuery(service: service)
        query[kSecReturnData as String] = kCFBooleanTrue as AnyObject
        query[kSecMatchLimit as String] = kSecMatchLimitOne as AnyObject
        
        var data: AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &data)
        
        if status == errSecSuccess {
            if let data = data as? Data {
                let unobj = unarchivedObject(data)
                unarchivedData = unobj as AnyObject?
            }
        } else {
            kCJLog("CJKeychainStore load fail\(status)")
        }
        return unarchivedData
    }
    
    /// 保存
    public class func save(service: String, data:Any) {
        var query = self.keychainQuery(service: service)
        SecItemDelete(query as CFDictionary)
        if let archivedData = archivedDataWithObject(data) {
            query[kSecValueData as String] = archivedData as AnyObject
        } else {
            kCJLog("CJKeychainStore archivedData fail\(data)")
        }
        let status = SecItemAdd((query as CFDictionary), nil)
        if status != errSecSuccess {
            kCJLog("CJKeychainStore save fail\(status)")
        }
    }
    
    /// 删除
    public class func delete(service: String) {
        let query = self.keychainQuery(service: service)
        let status = SecItemDelete(query as CFDictionary)
        if status != errSecSuccess {
            kCJLog("CJKeychainStore delete fail\(status)")
        }
    }
}
